package com.campus.lostandfound.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * 环境配置验证器
 * 在应用启动后验证所有必需的环境变量
 * 注意：测试环境下不启用此验证器
 */
@Component
@Profile("!test")  // 测试环境下不加载此组件
public class EnvironmentValidator {

    @Autowired
    private EnvironmentConfig config;

    @EventListener(ApplicationReadyEvent.class)
    public void validateEnvironment() {
        System.out.println("\n========================================");
        System.out.println("开始验证环境配置...");
        System.out.println("========================================");

        try {
            // 1. 验证必需的环境变量
            System.out.println("1. 验证必需的环境变量...");
            validateRequired("AES_ENCRYPTION_KEY", config.getAesEncryptionKey());
            validateRequired("DB_URL", config.getDbUrl());
            validateRequired("DB_PASSWORD", config.getDbPassword());

            // 2. 验证 AES 密钥长度
            System.out.println("2. 验证 AES 密钥长度...");
            int keyLength = config.getAesEncryptionKey().getBytes(StandardCharsets.UTF_8).length;
            if (keyLength != 16) {
                throw new IllegalArgumentException(
                    String.format("AES 密钥长度必须是 16 字节，当前: %d 字节", keyLength)
                );
            }
            System.out.println("   ✓ AES 密钥长度正确: 16 字节 (AES-128)");

            // 3. 验证数据库配置
            System.out.println("3. 验证数据库配置...");
            if (!config.getDbUrl().startsWith("jdbc:")) {
                throw new IllegalArgumentException("数据库 URL 格式不正确");
            }
            System.out.println("   ✓ 数据库配置格式正确");

            // 4. 验证 Redis 配置（如果配置了）
            System.out.println("4. 验证 Redis 配置...");
            if (config.getRedisPort() < 1 || config.getRedisPort() > 65535) {
                throw new IllegalArgumentException("Redis 端口号无效: " + config.getRedisPort());
            }
            System.out.println("   ✓ Redis 配置格式正确");

            // 输出配置摘要（脱敏）
            printConfigSummary();

            System.out.println("\n========================================");
            System.out.println("✓ 环境配置验证通过");
            System.out.println("========================================\n");

        } catch (Exception e) {
            System.err.println("\n========================================");
            System.err.println("✗ 环境配置验证失败");
            System.err.println("========================================");
            System.err.println("错误信息: " + e.getMessage());
            System.err.println("\n请检查以下内容:");
            System.err.println("1. 环境变量是否正确配置");
            System.err.println("2. 加密的配置是否使用正确的密钥");
            System.err.println("3. 参考项目根目录的配置文档");
            System.err.println("========================================\n");
            
            // 验证失败时终止应用启动
            throw new RuntimeException("环境配置验证失败", e);
        }
    }

    /**
     * 验证必需的配置项
     */
    private void validateRequired(String name, String value) {
        if (value == null || value.trim().isEmpty()) {
            throw new IllegalArgumentException("必需的环境变量未配置: " + name);
        }
        System.out.println("   ✓ " + name + ": 已配置");
    }

    /**
     * 打印配置摘要（脱敏）
     */
    private void printConfigSummary() {
        System.out.println("\n========================================");
        System.out.println("当前环境配置摘要（脱敏）");
        System.out.println("========================================");
        System.out.println("AES 密钥: " + maskString(config.getAesEncryptionKey()));
        System.out.println("JWT 密钥: " + maskString(config.getJwtSecretKey()));
        System.out.println("数据库 URL: " + maskUrl(config.getDbUrl()));
        System.out.println("数据库用户: " + config.getDbUsername());
        System.out.println("数据库密码: " + maskString(config.getDbPassword()));
        System.out.println("Redis 地址: " + config.getRedisHost() + ":" + config.getRedisPort());
        if (config.getRedisPassword() != null && !config.getRedisPassword().isEmpty()) {
            System.out.println("Redis 密码: " + maskString(config.getRedisPassword()));
        }
        System.out.println("========================================");
    }

    /**
     * 脱敏字符串（保留首尾，中间用 * 代替）
     */
    private String maskString(String str) {
        if (str == null || str.length() < 4) {
            return "****";
        }
        int showLength = Math.min(2, str.length() / 4);
        String start = str.substring(0, showLength);
        String end = str.substring(str.length() - showLength);
        return start + "****" + end;
    }

    /**
     * 脱敏 URL（只显示主机和数据库名）
     */
    private String maskUrl(String url) {
        if (url == null) {
            return "null";
        }
        // 简化显示，隐藏密码等敏感信息
        return url.split("\\?")[0] + "?...";
    }
}

